package com.bawan.vims.test;

import static org.junit.Assert.*;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.bawan.vims.common.IDGenerator;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;

/**
 * <p> Description	: XStreamTester.java </p>
 * <p> Copyright	: Copyright (c) 2015 by PCI-SUNTEK</p>
 * <p> Author 		: ZCC </p>
 * <p> Create		: 2015年5月27日 下午5:21:10 </p> 
 * <p> version 		: 1.0 </p>
 */
public class XStreamTester {
	class XmlDeclarationXStream extends XStream {
		private String encoding;
		private String version = "1.0";
		public XmlDeclarationXStream() {
			this("UTF-8", "1.0");
		}
		public XmlDeclarationXStream(String version, String encoding) {
			this.encoding = encoding;
			this.version = version;
		}
		public String getDeclaration() {
			return "<?xml version=\"" + this.version + "\" encoding=\"" + this.encoding + "\"?>\r\n";
		}
		public void toXML(Object arg0, OutputStream arg1){
			try {
				String dec = this.getDeclaration();
				byte[] bytesDesc = dec.getBytes(this.encoding);
				arg1.write(bytesDesc);
			} catch (Exception e) {
				e.printStackTrace();
			}
			super.toXML(arg0, arg1);
		}
		public void toXML(Object arg0, Writer arg1){
			try {
				arg1.write(this.getDeclaration());
			} catch (Exception e) {
				e.printStackTrace();
			}
			super.toXML(arg0, arg1);
		}
	}
	
	@Test
	public void testXml2Bean() {
		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
				+ "<MESSAGE Version=\"1.0\">"
				+ "<CV_HEADER MsgType=\"MSG_GET_VCU_LOG_RSP\" MsgSeq=\"1234\" />"
				+ "<RESULT Value=\"操作结果\" ErrorCode=\"错误码\" />"
				+ "<PAGE_INFO TotalNum=\"2\" BeginIndex=\"1\" EndIndex=\"2\" />" 
				+ "<LOG_INFO_LIST>"
				+ "<LOG_INFO>LOG 信息1</LOG_INFO>"
				+ "<LOG_INFO>LOG 信息1</LOG_INFO>"
				+ "</LOG_INFO_LIST>"
				+ "</MESSAGE>";
		XStream xstream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); //解决出现双下划线的问题
		xstream.processAnnotations(VCURecordPlan.class);
		VCURecordPlan vcuRecordPlan = (VCURecordPlan) xstream.fromXML(xml);
		System.out.println(xstream.toXML(vcuRecordPlan));
	}

	@Test
	public void testWriteList2XML() {
		VCURecordPlan recordPlan = new VCURecordPlan();
		recordPlan.setVersion("1.0");
		recordPlan.setCvHeader(new CVHeader("MSG_SET_VCU_RECORD_PLAN_REQ", 1));
		recordPlan.setResult(new Result("OK", "0"));
		recordPlan.setPageInfo(new PageInfo(20, 1, 5));
		List<Plan> plans = new ArrayList<XStreamTester.Plan>();
		plans.add(new Plan(1, 1, "2015-05-25 09:00:00", "17:30:00"));
		plans.add(new Plan(1, 2, "2015-05-26 08:30:00", "17:00:00"));
		plans.add(new Plan(1, 3, "2015-05-27 09:30:00", "18:30:00"));
		plans.add(new Plan(1, 4, "2015-05-28 10:00:00", "19:30:00"));
		PlanList planList = new PlanList();
		planList.setPlan(plans);
		recordPlan.setPlanList(planList);
		
		System.out.println("==================Bean to XML==================");
//		XStream xstream = new XmlDeclarationXStream();
		XStream xstream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); //解决出现双下划线的问题
		xstream.processAnnotations(recordPlan.getClass());
		System.out.println(xstream.toXML(recordPlan));
		/*System.out.println("=================XML to Bean===================");
		String xmlStr = xstream.toXML(recordPlan);
		
		VCURecordPlan vcuRecordPlan = (VCURecordPlan) xstream.fromXML(xmlStr);
		
		System.out.println(vcuRecordPlan);*/
		
		/**
		<?xml version="UTF-8" encoding="1.0"?>
		<MESSAGE Version="1.0">
		  <CV__HEADER MsgType="MSG_SET_VCU_RECORD_PLAN_REQ" MsgSeq="1"/>
		  <RESULT value="OK" ErrorCode="0"/>
		  <PAGE__INFO TotalNum="20" BeginIndex="1" EndIndex="5"/>
		  <PLAN__LIST>
		    <PLAN Cycle="1" Period="1" StartTime="2015-05-25 09:00:00" StopTime="17:30:00"/>
		    <PLAN Cycle="1" Period="2" StartTime="2015-05-26 08:30:00" StopTime="17:00:00"/>
		    <PLAN Cycle="1" Period="3" StartTime="2015-05-27 09:30:00" StopTime="18:30:00"/>
		    <PLAN Cycle="1" Period="4" StartTime="2015-05-28 10:00:00" StopTime="19:30:00"/>
		  </PLAN__LIST>
		</MESSAGE>
		**/
	}

	@XStreamAlias("MESSAGE")
	static class VCURecordPlan {
		@XStreamAsAttribute
		private String Version = "1.0";
		@XStreamAlias("CV_HEADER")
		private CVHeader cvHeader;
		@XStreamAlias("RESULT")
		private Result result;
		@XStreamAlias("PAGE_INFO")
		private PageInfo pageInfo;
		@XStreamAlias("PLAN_LIST")
		private PlanList planList;
		public Result getResult() {
			return result;
		}
		public void setResult(Result result) {
			this.result = result;
		}
		public String getVersion() {
			return Version;
		}
		public void setVersion(String version) {
			Version = version;
		}
		public CVHeader getCvHeader() {
			return cvHeader;
		}
		public void setCvHeader(CVHeader cvHeader) {
			this.cvHeader = cvHeader;
		}
		public PageInfo getPageInfo() {
			return pageInfo;
		}
		public void setPageInfo(PageInfo pageInfo) {
			this.pageInfo = pageInfo;
		}
		public PlanList getPlanList() {
			return planList;
		}
		public void setPlanList(PlanList planList) {
			this.planList = planList;
		}
		
		public String toString() {
			try {
				return ToStringBuilder.reflectionToString(this,
						ToStringStyle.MULTI_LINE_STYLE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}
	}
	static class Result {
		@XStreamAsAttribute
		private String value;
		@XStreamAsAttribute
		private String ErrorCode;
		public Result(String value, String errorCode) {
			super();
			this.value = value;
			ErrorCode = errorCode;
		}
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
		public String getErrorCode() {
			return ErrorCode;
		}
		public void setErrorCode(String errorCode) {
			ErrorCode = errorCode;
		}
		public String toString() {
			try {
				return ToStringBuilder.reflectionToString(this,
						ToStringStyle.MULTI_LINE_STYLE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}
	}
	static class CVHeader {
		@XStreamAsAttribute
		private String MsgType;
		@XStreamAsAttribute
		private int MsgSeq;
		public CVHeader(String msgType, int msgSeq) {
			super();
			MsgType = msgType;
			MsgSeq = msgSeq;
		}
		public String getMsgType() {
			return MsgType;
		}
		public void setMsgType(String msgType) {
			MsgType = msgType;
		}
		public int getMsgSeq() {
			return MsgSeq;
		}
		public void setMsgSeq(int msgSeq) {
			MsgSeq = msgSeq;
		}
		public String toString() {
			try {
				return ToStringBuilder.reflectionToString(this,
						ToStringStyle.MULTI_LINE_STYLE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}
	}
	static class PageInfo {
		@XStreamAsAttribute
		private int TotalNum;
		@XStreamAsAttribute
		private int BeginIndex;
		@XStreamAsAttribute
		private int EndIndex;
		public PageInfo(int totalNum, int beginIndex, int endIndex) {
			super();
			TotalNum = totalNum;
			BeginIndex = beginIndex;
			EndIndex = endIndex;
		}
		public int getTotalNum() {
			return TotalNum;
		}
		public void setTotalNum(int totalNum) {
			TotalNum = totalNum;
		}
		public int getBeginIndex() {
			return BeginIndex;
		}
		public void setBeginIndex(int beginIndex) {
			BeginIndex = beginIndex;
		}
		public int getEndIndex() {
			return EndIndex;
		}
		public void setEndIndex(int endIndex) {
			EndIndex = endIndex;
		}
		public String toString() {
			try {
				return ToStringBuilder.reflectionToString(this,
						ToStringStyle.MULTI_LINE_STYLE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}
	}
	static class PlanList {
		@XStreamImplicit(itemFieldName="PLAN")
		private List<Plan> plan;
		public List<Plan> getPlan() {
			return plan;
		}
		public void setPlan(List<Plan> plan) {
			this.plan = plan;
		}
		public String toString() {
			try {
				return ToStringBuilder.reflectionToString(this,
						ToStringStyle.MULTI_LINE_STYLE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}
	}
	static class Plan {
		@XStreamAsAttribute
		private int Cycle;
		@XStreamAsAttribute
		private int Period;
		@XStreamAsAttribute
		private String StartTime;
		@XStreamAsAttribute
		private String StopTime;
		
		public Plan(int cycle, int period, String startTime, String stopTime) {
			super();
			Cycle = cycle;
			Period = period;
			StartTime = startTime;
			StopTime = stopTime;
		}
		public int getCycle() {
			return Cycle;
		}
		public void setCycle(int cycle) {
			Cycle = cycle;
		}
		public int getPeriod() {
			return Period;
		}
		public void setPeriod(int period) {
			Period = period;
		}
		public String getStartTime() {
			return StartTime;
		}
		public void setStartTime(String startTime) {
			StartTime = startTime;
		}
		public String getStopTime() {
			return StopTime;
		}
		public void setStopTime(String stopTime) {
			StopTime = stopTime;
		}
		public String toString() {
			try {
				return ToStringBuilder.reflectionToString(this,
						ToStringStyle.MULTI_LINE_STYLE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "";
		}
	}
}
